package com.xvyy.tingshu.album.service.impl;


import com.xvyy.tingshu.album.mapper.*;
import com.xvyy.tingshu.album.service.AlbumAttributeValueService;
import com.xvyy.tingshu.album.service.AlbumInfoService;
import com.xvyy.tingshu.common.constant.RedisConstant;
import com.xvyy.tingshu.common.constant.SystemConstant;
import com.xvyy.tingshu.common.execption.TsException;
import com.xvyy.tingshu.common.rabbit.constant.MqConst;
import com.xvyy.tingshu.common.rabbit.service.RabbitService;
import com.xvyy.tingshu.common.util.AuthContextHolder;
import com.xvyy.tingshu.model.album.*;
import com.xvyy.tingshu.query.album.AlbumInfoQuery;
import com.xvyy.tingshu.user.client.UserInfoFeignClient;
import com.xvyy.tingshu.vo.album.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Autowired
    private AlbumInfoMapper albumInfoMapper;
    @Autowired
    private AlbumAttributeValueMapper albumAttributeValueMapper;
    @Autowired
    private AlbumStatMapper albumStatMapper;
    @Autowired
    private AlbumAttributeValueService albumAttributeValueService;
    @Autowired
    private TrackInfoMapper trackInfoMapper;
    @Autowired
    private RabbitService rabbitService;
/*    @Autowired
    private BaseCategory2Mapper baseCategory2Mapper;
    @Autowired
    private BaseCategory3Mapper baseCategory3Mapper;
    @Autowired
    private AlbumInfoFeignClient albumInfoFeignClient;*/
    @Autowired
    private UserInfoFeignClient userInfoFeignClient;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    // 开启事务 rollbackFor = Exception.class 表示遇到异常时回滚
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {

        // 0. 创建专辑信息对象 AlbumInfo
        AlbumInfo albumInfo = new AlbumInfo();

        AlbumInfoServiceImpl proxy = (AlbumInfoServiceImpl) AopContext.currentProxy();

        // 1. 基本信息表保存 album_info
        // 拷贝基本信息表字段
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        // 根据AuthContextHolder获取当前登录用户的id
        Long userId = AuthContextHolder.getUserId();
        albumInfo.setUserId(userId);// 设置当前登录用户的id
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);// 设置专辑状态为审核通过
        //判断专辑付费类型，如果不是免费，设置试听初始值5
        if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoVo.getPayType())) {
            albumInfo.setTracksForFree(5);
        }
        albumInfoMapper.insert(albumInfo);

        // 2. 专辑属性值表保存 album_attribute_value
        // 获取专辑属性值列表
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        //判断是否有专辑属性值
        if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            //遍历专辑属性值列表
            for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();// 创建专辑属性值对象
                albumAttributeValue.setAlbumId(albumInfo.getId());// 设置专辑id
                albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());// 设置属性id
                albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());// 设置属性值id
                //保存专辑属性值信息
                albumAttributeValueMapper.insert(albumAttributeValue);
            }
        }

        // 3. 初始化专辑统计表(四个维度的统计信息)
        proxy.initAlbumStat(albumInfo.getId());

        // 4. 将专辑信息保存在ES中 （rpc / message）
        if (albumInfoVo.getIsOpen().equals("1")) {
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_UPPER, albumInfo.getId().toString());
            log.info("专辑微服务发送消息到搜索微服务指定的队列，完成专辑{}上架成功", albumInfo.getId());
        }

    }

    @Override
    public IPage<AlbumListVo> findUserAlbumPage(IPage<AlbumListVo> albumInfoVoPage, AlbumInfoQuery albumInfoQuery) {
        albumInfoQuery.setUserId(AuthContextHolder.getUserId()); // 设置用户id
        return albumInfoMapper.findUserAlbumPage(albumInfoVoPage, albumInfoQuery);
    }

    @Override
    public AlbumInfo getAlbumInfo(Long albumId) {
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);

        if (null == albumInfo) {
            throw new TsException(201, "专辑不存在");
        }

        List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueMapper.selectList(
                new LambdaQueryWrapper<AlbumAttributeValue>()
                        .eq(AlbumAttributeValue::getAlbumId, albumId)
        );
        albumInfo.setAlbumAttributeValueVoList(albumAttributeValues);
        return albumInfo;
    }

    @Override
    public void updateAlbumInfo(Long albumId, AlbumInfoVo albumInfoVo) {
        // 0. 删除缓存数据，防止缓存和数据库数据不一致，再更新数据库数据
        String cacheKey = RedisConstant.CACHE_INFO_PREFIX + albumId;
        stringRedisTemplate.delete(cacheKey);
        Long userId = AuthContextHolder.getUserId();
        // 1. 修改专辑基本信息
        // 1.1. 查询专辑的老数据
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        if (null == albumInfo) {
            throw new TsException(201, "专辑不存在");
        }
        // 1.2. 拷贝基本信息表字段，有的话就直接拷贝，没有就用原来的对象
        BeanUtils.copyProperties(albumInfoVo, albumInfo);

        // 1.3. 判断付费类型
        // 如果是免费的，设置原价为0.00，折扣为-1.00，试听时间为0
        if (albumInfoVo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_FREE)) {
            albumInfo.setTracksForFree(0);
            albumInfo.setDiscount(new BigDecimal("-1.00"));
            albumInfo.setVipDiscount(new BigDecimal("-1.00"));
            albumInfo.setPrice(new BigDecimal("0.00"));
        } else {
            // 1.4 如果不是免费的，设置试听时间为5
            albumInfo.setTracksForFree(5);
        }

        // 1.3. 更新基本信息表
        albumInfoMapper.updateById(albumInfo);

        // 2. 修改专辑的标签信息
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        // 2.1 删除老的标签信息，添加新的标签信息
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();

        // 2.2 新增这个专辑的新标签
        List<AlbumAttributeValue> albumAttributeValueList = albumAttributeValueVoList.stream().map(albumAttributeValueVo -> {
            // 创建专辑属性值对象
            AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
            albumAttributeValue.setAlbumId(albumId);
            albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
            albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());
            return albumAttributeValue;
        }).collect(Collectors.toList());
        // 2.3 判断是否有标签信息
        if (!CollectionUtils.isEmpty(albumAttributeValueList)) {
            // 批量保存标签信息
            albumAttributeValueService.saveBatch(albumAttributeValueList);
        }
        // 3. 同步修改到ES中 message 0 --> 1   如果1 --> 1 只是更新覆盖
        if (albumInfoVo.getIsOpen().equals("1")) {
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_UPPER, albumId.toString());
            log.info("专辑微服务发送消息到收缩为服务指定的队列，完成专辑{}更新成功", albumId);
        }/*else {
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, albumId.toString());
            log.info("专辑微服务发送消息到收缩为服务指定的队列，完成专辑{}删除成功" , albumId);
        }*/
    }

    @Override
    public void removeAlbumInfo(Long albumId) {
        Long userId = AuthContextHolder.getUserId();
        if (userId == null) {
            throw new TsException(201, "用户不存在，删除失败");
        }
        // 1. 根据专辑id删除基本信息表include_track_count表
        Long count = trackInfoMapper.selectCount(
                new LambdaQueryWrapper<TrackInfo>().eq(TrackInfo::getAlbumId, albumId));
        // 判断是否存在声音
        if (count > 0) {
            throw new TsException(201, "该专辑下还有声音不能删除");
        }
        // 不存在则根据albumId删除基本信息表
        albumInfoMapper.deleteById(albumId);
        // 2. 根据专辑id删除album_attribute_value表 删除统计信息
        albumStatMapper.delete(
                new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, albumId));
        // 3. 根据专辑id删除album_stat表 删除标签信息
        albumAttributeValueMapper.delete(
                new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));

        // 4. 将专辑信息从ES中删除 message
        rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, albumId.toString());
        log.info("专辑微服务发送消息到收缩为服务指定的队列，完成专辑{}下架成功", albumId);
    }

    @Override
    public List<AlbumInfo> findUserAllAlbumList(Long userId) {
        return albumInfoMapper.selectList(
                new LambdaQueryWrapper<AlbumInfo>()
                        .eq(AlbumInfo::getUserId, userId)
                        .eq(AlbumInfo::getIsDeleted, 0));
    }

    @Override
    public AlbumStatVo getAlbumInfoStat(Long albumId) {

        return albumStatMapper.getAlbumInfoStat(albumId);
    }

    @Override
    public List<TrackListVo> getTrackListVo(List<Long> collectTrackIdList) {

        List<TrackInfo> trackInfoList = trackInfoMapper.selectBatchIds(collectTrackIdList);

        return trackInfoList.stream().map(trackInfo -> {
            TrackListVo trackListVo = new TrackListVo();
            BeanUtils.copyProperties(trackInfo, trackListVo);
            trackListVo.setTrackId(trackInfo.getId());
            return trackListVo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<Long> getAlbumInfoIdList() {
        List<AlbumInfo> albumInfoList = albumInfoMapper.selectList(null);
        return albumInfoList.stream().map(AlbumInfo::getId).collect(Collectors.toList());
    }


    @Transactional(rollbackFor = Exception.class)
    public void initAlbumStat(Long albumId) {
        ArrayList<String> albumStatTypes = new ArrayList<>();

        albumStatTypes.add(SystemConstant.ALBUM_STAT_PLAY);//401
        albumStatTypes.add(SystemConstant.ALBUM_STAT_SUBSCRIBE);//402
        albumStatTypes.add(SystemConstant.ALBUM_STAT_BROWSE);//403
        albumStatTypes.add(SystemConstant.ALBUM_STAT_COMMENT);//404

        //遍历专辑统计类型列表
        for (String albumStatType : albumStatTypes) {
            AlbumStat albumStat = new AlbumStat();// 创建专辑统计对象
            albumStat.setAlbumId(albumId);// 设置专辑id
            albumStat.setStatType(albumStatType);// 设置统计类型
            albumStatMapper.insert(albumStat);// 保存专辑统计信息
        }
    }
}
